<template>
  <div class="echarts-wall" :style="echartsStyle">
    <div class="dot-bg" v-if="loading"></div>
    <div class="dot-elastic dotClass" v-if="loading"></div>
    <div class="echarts-content" ref="echartsDom"></div>
  </div>
</template>

<script lang="ts" setup>
// @ts-ignore
import {ElMessage} from "element-plus";
// @ts-ignore
import screenConfig, {getMarkPoint} from '@/components/global/bigscreen/screen_config'
// @ts-ignore
import {getCurrentInstance, onMounted, ref, watch} from "vue";

defineOptions({
  name: "Echarts3DBar"
});

const loading = ref<boolean>(false);

const props = defineProps({
      //bar 颜色
      barColor: {
        type: Array, default() {
          return ['red']
        }
      },
      //bar 宽度
      barWidth: {
        type: Number, default: screenConfig.barWidth,
      },
      //上下展示层叠加
      barStack: {type: Boolean, default: false},
      //单一分类是的bar 处理itemStyle
      singBaseModel: {type: Boolean, default: false},
      //竖立显示名称
      erectName: {type: Boolean, default: false},
      //显示legend
      legendShow: {type: Boolean, default: false},
      legendOrient: {type: String, default: 'vertical'},//vertical
      legendLeft: {type: String, default: 'left'},//vertical
      //显示数据值
      seriesLabelShow: {type: Boolean, default: false},
      //值的位置
      seriesLabelPosition: {type: String, default: 'top'},
      //值的位置
      seriesLabelColor: {type: String, default: 'red'},
      //显示y轴value值
      yAxisLabelShow: {type: Boolean, default: false},
      //y轴分割线
      yAxisSplitLineShow: {type: Boolean, default: false},
      //y轴分割线颜色
      yAxisSplitLineColor: {type: String, default: '#FFF'},
      //y轴分割线样式
      yAxisSplitLineType: {type: String, default: 'solid'},
      //y轴单位
      yAxisSplitValueUit: {type: String, default: ''},
      //y轴小刻度显示
      yAxisAxisTick: {type: Boolean, default: false},
      //y轴显示
      yAxisLineShow: {type: Boolean, default: false},
      //y轴样式
      yAxisLineType: {type: String, default: 'solid'},
      yAxisLineColor: {type: String, default: 'red'},
      //x轴
      xAxisLineColor: {type: String, default: 'red'},
      //x轴小刻度显示
      xAxisAxisTick: {type: Boolean, default: false},
      //x轴分割线
      xAxisSplitLineShow: {type: Boolean, default: false},
      //x轴分割线颜色
      xAxisSplitLineColor: {type: String, default: '#FFF'},
      //y轴分割线样式
      xAxisSplitLineType: {type: String, default: 'solid'},
      //x轴倾斜度
      xAxisRotate: {type: Number, default: 0},
      //x轴样式
      xAxisLineType: {type: String, default: 'solid'},
      //x轴显示
      xAxisLineShow: {type: Boolean, default: false},
      //x轴name显示
      xAxisLabelShow: {type: Boolean, default: false},
      //自动滚动
      autoMove: {type: Boolean, default: false},
      endDataZoom: {type: Number, default: 5},
      dataZoom: {
        type: Array, default: function () {
          return [{type: 'slider', show: false, height: 15}]
        }
      },
      title: {
        type: Object, default: function () {
          return {}
        }
      },
      grid: {
        type: Object, default: function () {
          return {
            left: '10',
            top: '10',
            right: '10',
            bottom: '20'
          }
        }
      },
      url: {
        type: String, default: ''
      },
      params: {
        type: Object, default: {}
      },
      fontColor: {
        type: Object, default: function () {
          return {
            x: screenConfig.nameColor,
            y: screenConfig.yNameColor,
          }
        }
      },
    }
);
// dom 组件
const echartsDom = ref<any>(null);

const echartsStyle = ref<any>({});

// @ts-ignore
let {proxy} = getCurrentInstance()

//
let myEcharts: any = null;

onMounted(() => {
  initEcharts()
})

//监听查询条件
watch(() => props.params, () => {
  initEcharts();
})
let dataZoomMaxLength: number = 0;
let timer: any = null;
let startDataZoom = 0;
let endDataZoom = props.endDataZoom;
const initEcharts = () => {
  getData().then((option: any) => {
    myEcharts = proxy.$echarts.init(echartsDom.value);
    if (myEcharts) {
      myEcharts.clear();
      myEcharts.setOption(option)
      if (props.autoMove) {
        myEcharts.on('mouseover', stop)
        myEcharts.on('mouseout', goMove)
        autoMove();
      }
    }
  });
}
const autoMove = () => {
  if (timer) return
  timer = setInterval(() => {
    console.log(startDataZoom, endDataZoom, dataZoomMaxLength)

    if (endDataZoom === dataZoomMaxLength) {
      startDataZoom = 0
      endDataZoom = props.endDataZoom
      myEcharts.setOption({
        dataZoom: {
          startDataZoom, // 从头开始。
          endDataZoom
        }

      })
    } else {
      myEcharts.setOption({
        dataZoom: {
          startValue: ++startDataZoom, // 从头开始。
          endValue: ++endDataZoom
        }

      })
    }
  }, 3000);
}
const stop = (...args: any[]) => {
  console.log(args)
  clearInterval(timer)
  timer = null
}
const goMove = (...args: any[]) => {
  console.log(args)
  autoMove()
}
// x轴属性
const xAxis = (xData: any) => {
  let axis = {
    type: 'category',
    boundaryGap: false, // 紧挨边缘
    axisTick: {
      // x轴上的小刻度
      show: props.xAxisAxisTick
    },
    splitLine: {
      // 网格线
      show: props.xAxisSplitLineShow,
      lineStyle: {
        type: props.xAxisSplitLineType, // dotted 虚线 solid 实线
        color: props.xAxisSplitLineColor
      }
    },
    axisLine: {
      show: props.xAxisLineShow,
      lineStyle: {
        type: props.xAxisLineType,
        color: props.xAxisLineColor
      }
    },
    axisLabel: {
      show: props.xAxisLabelShow,
      // x轴样式
      margin: 5, // x轴距离文字距离
      interval: 0, //显示所有X轴信息
      rotate: props.xAxisRotate, //倾斜角度
      textStyle: {
        color: props.fontColor.x,
        fontSize: screenConfig.fontSizeX
      }, formatter: function (value: string, index: number) {
        if (props.erectName) {
          let str = value.split("");
          return str.join("\n");
        } else {
          return value;
        }
      }
    },
    data: xData
  }
  return axis;
}
/**
 * y轴属性
 */
const yAxis = () => {
  return {
    name: '',
    nameTextStyle: {
      color: screenConfig.yNameColor,
      fontSize: screenConfig.yNameFontSize,
    },
    type: 'value',
    splitLine: {
      // 网格线
      show: props.yAxisSplitLineShow,
      lineStyle: {
        type: props.yAxisSplitLineType, // dotted 虚线 solid 实线
        color: props.yAxisSplitLineColor
      }
    },
    axisLine: {
      show: props.yAxisLineShow,
      lineStyle: {
        type: props.yAxisLineType,
        color: props.yAxisLineColor
      }
    },
    axisTick: {
      show: props.yAxisAxisTick
    },
    axisLabel: {
      show: props.yAxisLabelShow,
      //y 轴样式
      formatter: (value: any, index: any) => {
        if (props.yAxisSplitValueUit === '') {
          if (value >= 10000) {
            return `${(value / 10000).toFixed(1)}W`
          } else if (value >= 1000) {
            return `${(value / 1000).toFixed(1)}K`
          }
        }
        return `${(value)}`
      },
      color: '#A1A7B3',
      fontSize: 14,
      textStyle: {
        color: screenConfig.valueColor
      }
    }
  }
}

const tooltip = (i: number) => {
  let formatter = '{b} : {c}';
  if (i > 1) {
    formatter = '';
  }
  return {
    show: true,
    trigger: 'item', //axis , item
    backgroundColor: 'RGBA(0, 49, 85, 1)',
    borderColor: 'rgba(0, 151, 251, 1)',
    borderWidth: 1,
    borderRadius: 0,
    textStyle: {
      color: '#BCE9FC',
      fontSize: 16,
      align: 'left',
    },
    formatter,

  }
}

const legend = () => {
  return {
    show: props.legendShow,
    orient: props.legendOrient,
    left: props.legendLeft,
    textStyle: {
      fontSize: screenConfig.legendFontSize,
      fontFamily: screenConfig.legendFontFamily,
      color: screenConfig.legendFontColor,
    },
  }
}

//3d bar 初始化面
const initBarView = () => {
  // 绘制左侧面
  const wid = props.barWidth;
  const w1 = Math.sin(Math.PI / 6) * wid; //4
  const w2 = Math.sin(Math.PI / 3) * wid; // 6.8
  const snapHeight = wid / 2;
  const CubeLeft = proxy.$echarts.graphic.extendShape({
    shape: {
      x: 0,
      y: 0,
    },
    buildPath: function (ctx: any, shape: any) {
      const xAxisPoint = shape.xAxisPoint;
      const c0 = [shape.x, shape.y];
      const c1 = [shape.x - w2, shape.y];
      const c2 = [shape.x - w2, xAxisPoint[1]];
      const c3 = [shape.x, xAxisPoint[1]];
      ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath();
    },
  });
// 绘制右侧面
  const CubeRight = proxy.$echarts.graphic.extendShape({
    shape: {
      x: 0,
      y: 0,
    },
    buildPath: function (ctx: any, shape: any) {
      const xAxisPoint = shape.xAxisPoint;
      const c1 = [shape.x, shape.y];
      const c2 = [shape.x, xAxisPoint[1]];
      const c3 = [shape.x + w1, xAxisPoint[1] - w2 + snapHeight];
      const c4 = [shape.x + w1, shape.y - w2 + snapHeight];
      ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
    },
  });
// 绘制顶面
  const CubeTop = proxy.$echarts.graphic.extendShape({
    shape: {
      x: 0,
      y: 0,
    },
    buildPath: function (ctx: any, shape: any) {
      //
      const c1 = [shape.x, shape.y];
      const c2 = [shape.x + w1, shape.y - w2 + snapHeight]; //右点
      const c3 = [shape.x - w2 + w1, shape.y - w2 + snapHeight];
      const c4 = [shape.x - w2, shape.y];
      ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
    },
  });
// 三个面图形
  proxy.$echarts.graphic.registerShape('CubeLeft', CubeLeft);
  proxy.$echarts.graphic.registerShape('CubeRight', CubeRight);
  proxy.$echarts.graphic.registerShape('CubeTop', CubeTop);
}
const getData = () => {
  return new Promise((resolve, reject) => {
        if (props.url) {
          loading.value = true;
          proxy.$http.post(props.url, props.params)
              .then((apiResponse: any) => {
                    if (apiResponse.success || apiResponse.data) {
                      //x轴数据
                      let xData: any = [];

                      let yValue: any = [];

                      //series
                      let series: any = [];
                      //获取的数据
                      let echartsData = apiResponse.data.echartsData;
                      let i = 0;
                      Object.keys(echartsData).forEach((key: string) => {
                        if (i === 0) {
                          dataZoomMaxLength = echartsData[key].length
                          for (let x = 0; x < echartsData[key].length; x++) {
                            let data = echartsData[key][x];
                            xData.push(data.name);
                            yValue.push(data.value);
                          }
                          initBarView();
                          let mSeries: any = {
                            name: key,
                            data: yValue,
                            type: 'bar',
                            barWidth: 1,
                            label: {
                              show: props.seriesLabelShow,
                              position: props.seriesLabelPosition,
                              textStyle: {
                                color: props.seriesLabelColor,
                                fontSize: screenConfig.markPointFontSize
                              }
                            },
                            tooltip: {
                              show: false,
                            },
                            symbolSize: [30, 8],
                            itemStyle: {}
                          };
                          series.push(mSeries);
                          series.push({
                            type: 'custom',
                            renderItem: (params: any, api: any) => {
                              const location = api.coord([api.value(0), api.value(1)]);
                              location[0] = location[0] + props.barWidth * 0;
                              const xlocation = api.coord([api.value(0), 0]);
                              xlocation[0] = xlocation[0] + props.barWidth * 0;
                              return {
                                type: 'group',
                                children: [
                                  {
                                    type: 'CubeLeft',
                                    shape: {
                                      api,
                                      xValue: api.value(0),
                                      yValue: api.value(1),
                                      x: location[0],
                                      y: location[1],
                                      xAxisPoint: xlocation,
                                    },
                                    style: {
                                      fill: new proxy.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                        {
                                          offset: 0,
                                          color: '#059de6',
                                        },
                                        {
                                          offset: 1,
                                          color: '#059de6',
                                        },
                                      ]),
                                    },
                                  },
                                  {
                                    type: 'CubeRight',
                                    shape: {
                                      api,
                                      xValue: api.value(0),
                                      yValue: api.value(1),
                                      x: location[0],
                                      y: location[1],
                                      xAxisPoint: xlocation,
                                    },
                                    style: {
                                      fill: new proxy.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                        {
                                          offset: 0,
                                          color: '#254193',
                                        },
                                        {
                                          offset: 1,
                                          color: '#254193',
                                        },
                                      ]),
                                    },
                                  },
                                  {
                                    type: 'CubeTop',
                                    shape: {
                                      api,
                                      xValue: api.value(0),
                                      yValue: api.value(1),
                                      x: location[0],
                                      y: location[1],
                                      xAxisPoint: xlocation,
                                    },
                                    style: {
                                      fill: new proxy.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                        {
                                          offset: 0,
                                          color: '#17e0fe',
                                        },
                                        {
                                          offset: 1,
                                          color: '#17e0fe',
                                        },
                                      ]),
                                    },
                                  },
                                ],
                              };
                            },
                            color: 'blue',
                            data: yValue,
                          });
                        }
                        i++;
                      });
                      let dataZoom = props.dataZoom;
                      if (props.autoMove) {
                        dataZoom = [{
                          show: false,
                          type: "slider", // 这个 dataZoom 组件是 slider 型 dataZoom 组件
                          startValue: startDataZoom, // 从头开始。
                          endValue: endDataZoom
                        }]
                      }
                      let option: any = {
                        backgroundColor: 'transparent',
                        legend: legend(),
                        tooltip: tooltip(i),
                        xAxis: xAxis(xData),
                        yAxis: yAxis(),
                        title: props.title,
                        grid: props.grid,
                        dataZoom,
                        series
                      };
                      if (props.yAxisSplitValueUit != '') {
                        option.yAxis.name = props.yAxisSplitValueUit
                      }


                      loading.value = false;
                      resolve(option);
                    } else {
                      ElMessage.error("数据格式异常,本组件接收数据类型")
                    }
                  }
                  ,
                  (err: any) => {
                    reject(err);
                  }
              )
          ;
        } else {
          reject("无法获取请求地址");
        }
      }
  )
}
</script>